/**
 *
 * Copyright Pact Lab of H.I.T.
 *
 * Designed and Implemented by Grid Researching Group, 
 * Pact Lab, Harbin
 * 
 * This Project is part of the national 973 Project:
 * Internet Based Virtual Computing Environment
 *
 * http://pact518.hit.edu.cn
 * 
 * Author:       Meteor <meteorlxk@gmail.com> 
 * Copyright:    pact518 
 * Version:      1.0
 * Created:      2008-12-15 
 * LastModified: 2008-12-15
 */
package edu.hit.pact.pgse.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * @author Meteor
 *
 */
public class Utilities {
	
	public static String getLocalIp() throws UnknownHostException {
		InetAddress inet = InetAddress.getLocalHost();
		return inet.getHostAddress();
	}
	
	public static String getHostAddress(String host) throws UnknownHostException{
		InetAddress address = InetAddress.getByName(host);
		return address.getHostAddress();
	}
	
	public static String getDateString() {
		Date date = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
		return df.format(date);
	}
	
	public static String getDay(){
		Date date = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		return df.format(date);
	}
	
	public static long getDateInMillisecond() {
		Date date = new Date();
		return date.getTime();
	}
	
	/*
	 * reverse url's host name.
	 * for example. 
	 * 1. the URL of http://www.google.com would reverse to http://moc.elgoog.www
	 * 2. the URL of http://www.google.com:8080 would reverse to http://0808:moc.elgoog.www
	 * 3. the URL of http://www.google.com/index.html would reverse to http://moc.elgoog.www/index.html
	 * 4. the URL of http://www.google.com:8080/index.html would reverse to http://0808:moc.elgoog.www/index.html
	 */
	public static String reverseUrlHost(URL url) {
		StringBuffer fullHostName = new StringBuffer();
		if (url.getPort() == -1) {
			fullHostName.append(url.getHost());
		} else {
			fullHostName.append(url.getHost() + ":" + url.getPort());
		}//end if
		
		String oldFullHostName = fullHostName.toString();
		String newFullHostName = fullHostName.reverse().toString();
		return url.toString().replaceFirst(oldFullHostName, newFullHostName);
	}
	
	public static String readStringFromFile(String fileName) throws Exception{
		return new String(readBytesFromFile(fileName));
	}
	
	public static byte[] readBytesFromFile(String fileName) throws Exception{
		File file = new File(fileName);
		InputStream inputStream = new FileInputStream(file);
		DataInputStream dataStream = new DataInputStream(inputStream);
		
		int fileLength;
		if(file.length() < Integer.MAX_VALUE)
		{
			fileLength = (int)file.length();
		}else{
			fileLength = Integer.MAX_VALUE;
		}
		
		if(fileLength == 0){
			return null;			
		}

		byte[] content = new byte[fileLength];
		try {
			for (int i = 0; i < fileLength; i++) {
				content[i] = dataStream.readByte();
			}
		}catch(EOFException e1){			
		}
		
		return content;
	}
	
	public static List<String> readListFromFile(String fileName) throws Exception {
		List<String> lines = new ArrayList<String>();
		
		BufferedReader reader = new BufferedReader(new FileReader(fileName));
		
		String temp = null;
		while ((temp = reader.readLine()) != null) {
			if (temp.length() > 0) {
				lines.add(temp);
			}
		}
		
		reader.close();
		
		return lines;	
	}
	
	public static boolean deleteFile(String fileName) throws Exception {
		File file = new File(fileName);
		return file.delete();
	}
	
	public static void emptyFile(String fileName) throws Exception{
		writeToFile(fileName, "", "UTF-8");
	}
	
	public static void writeToFile(String fileName, String content, String charSet) throws Exception {
		File file = new File(fileName);
		OutputStreamWriter out =new OutputStreamWriter(
				new FileOutputStream(file), charSet);
		out.write(content);
		out.flush();
		out.close();
	}
	
	public static void writeToFileAppend(String fileName, String content)
			throws Exception {
		FileWriter fw = new FileWriter(fileName, true);
		
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write(content);
		bw.write("\n");
		
		bw.flush();
		bw.close();
	}

	public static void writeToFileAppend(String fileName, List<String> content)
			throws Exception {
		FileWriter fw = new FileWriter(fileName, true);
		
		BufferedWriter bw = new BufferedWriter(fw);
		for (int i = 0; i < content.size(); i++) {
			String oneLine = content.get(i);
			bw.write(oneLine);
			bw.write("\n");
		}
		
		bw.close();
	}
	
	private static class SuffixFilter implements FilenameFilter {
		String str = null;
		
		public SuffixFilter(String str) {
			this.str = str;
		}

		public boolean accept(File dir, String name) {
			if (name.endsWith(str)) {
				return true;
			}
			return false;
		}
	}	
	
	public static List<String> listDir(File dir, String suffix) {
		FilenameFilter filter = new SuffixFilter(suffix);
		File[] list = dir.listFiles(filter);
		if (list == null) {
			return null;
		}
		
		List<String> pathList = new ArrayList<String>();
		for (int i = 0; i < list.length; i ++) {
			pathList.add(list[i].getAbsolutePath());
		}
		return pathList;
	}
	
	public static boolean createdDir(String dirPath) {
		File file = new File(dirPath);
		if(!file.isDirectory()){
			file.mkdirs();
			return true;
		}
		return false;
		
	}
	
	public static Properties loadProperties(String fileName) {
		Properties p = new Properties();
			
		try {
			InputStream istream = Utilities.getInputString(fileName);
			p.load(istream);
			istream.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		
		return p;
	}
	
	public static InputStream getInputString(String fileName) throws FileNotFoundException {
		//String realConfFile = "/" + supportedFilePath;
		
		//InputStream istream = Utilities.class.getResourceAsStream(realConfFile);
		
		String realConfFile = fileName;
		
		InputStream istream = new FileInputStream(realConfFile);
		
		return istream;
	}
	
	public static InputStream String2InputStream(String str) {
		ByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes());
		return stream;
	}
	
	public static String inputStream2String(InputStream is) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(is));
		StringBuffer buffer = new StringBuffer();
		String line = "";
		while ((line = in.readLine()) != null) {
			buffer.append(line + "\n");
		}//end while
		in.close();
		return buffer.toString();
	}
	
	public static byte[] getBytes(InputStream is, int maxContentLength) throws IOException {
        byte[] data = null;
       
        Collection<byte[]> chunks = new ArrayList<byte[]>();
        byte[] buffer = new byte[1024];
        int read = -1;
        int size = 0;
       
        while ((read = is.read(buffer)) != -1) {
            if (read > 0) {
                byte[] chunk = new byte[read];
                System.arraycopy(buffer, 0, chunk, 0, read);
                chunks.add(chunk);
                size += chunk.length;
            }
            
            if (size > maxContentLength) {
            	break;
            }
        }//end while ((read = is.read(buffer)) != -1)
       
        if (size > 0) {
            ByteArrayOutputStream bos = null;
            try {
                bos = new ByteArrayOutputStream(size);
                for(byte[] chunk : chunks) {
                    bos.write(chunk);
                }
                data = bos.toByteArray();
            } finally {
                if (bos != null) {
                    bos.close();
                }
            }//end try
        }//end  if (size > 0)
        
        return data;
    }
	
	public static Set<String> parse(InputStream istream) throws IOException {
		InputStreamReader inputStreamReader = new InputStreamReader(istream, "UTF-8");
		BufferedReader reader = new BufferedReader(inputStreamReader);
		return parseLines(reader);
	}
	
	private static Set<String> parseLines(BufferedReader reader)
			throws IOException {
		Set<String> set = new HashSet<String>();
		String temp = null;
		while ((temp = reader.readLine()) != null) {
			if (temp.startsWith("#") || temp.startsWith(" ")
					|| temp.startsWith("\t")) {
				continue;
			} else if (temp.length() == 0) {
				continue;
			}//end if
			set.add(temp);
		}//end while
		return set;
	}
	
	static final String regexFileFilter = "\\\\|\\.|\\*|\\||<|>|/|\\?|\"|:|\\s" ;
	static final Pattern p = Pattern.compile(regexFileFilter);
	public static synchronized String filterFileName(String srcFileName)
	{
		return p.matcher(srcFileName).replaceAll("");
	}
}
